
// JS Interpretator tests

Object.prototype.test = "test"
Object.prototype.__type__ = 123
Function.prototype.foo = "foo"
Function.bar = "bar"

print("type", {}.__type__)

function test(a, b, c) {
    //print(test.caller)
    //print(a,b,c)
    if( test.caller === test ) return this;
    var x = new test
    print("arguments", arguments.length, arguments)
    return x
}

print(test)
print(test.foo)

test.prototype.__class__ = test
test.prototype.__type__ = 0xdeadbeef
//test.prototype.__proto__ = test.prototype
test.prototype.__new__ = function(){
    this.x = 456
}
test.prototype.toString = function() {return "<test>"}

t = new test(1,2,3)

test.static = 123
t.x = 123

print("t", t)
print(t.__new__.call(t))
print("t.x", t.x)
print("static", test.static)
print(t.__class__, t.__type__, t.__proto__)
print(t.__proto__ === test.prototype, t instanceof test)

print(
    true instanceof Boolean, 
    123 instanceof Number, 
    "abc" instanceof String, 
    test instanceof Function,
    [] instanceof Array,
    {} instanceof Object
)

function testContext () {
    print("this.y", this.y)
    print(this)
}

testContext.prototype = {
    "y" : 987
}

call_ = (function (){
    t1 = test(4,5,6)
    t2 = new testContext()
})();

//f = function(x) x*x

//print(f(2))

o = {x:1}
ox = o.x

delete o.x
print("o.x", ox, o.x)

try {
    throw Error("error")
}
catch(e) {
    print(e)
} finally {
    print("finally")
}

eval("/* ... */ print('hello from' + ' ' + 'eval!')")

a = "a.b.c".split(".")
b = Array.prototype.slice.call(a, 1)
b.push(4)
print(b, b[1])

for( var i=0; i<4; i++) {
    if( i == 2) continue
    print(i)
}

desc = "test"

switch(desc) {
    case "test": 
        print("case A")
    case "def":
        print("case B")
    default:
        print("case default")
}

switch(2) {
    case 1: 
        print("case 1")
    case 2:
        print("case 2")
        break
    default:
        print("case default")
}

var NUMBER = 1,
    STRING = 2,
    FUNCTION = 3,
    BOOLEAN = 4,
    OBJECT = 5;

function sw(t) {
    switch(t) {
      case "number": 
        return NUMBER
      case "string": 
        return STRING
      case "function": 
        return FUNCTION
      case "boolean": 
        return BOOLEAN
      case "object": 
        return OBJECT
    }
    return 123
}

print("switch", sw("function"))

var a = 1
function testScope() {
  var b = 2
  function bar() {
    a = 10
    b = 20
  }
  bar()
  return [a, b]
}

print(testScope(), a)

print("abcabc".replace(/a(bc)/g, "d$1").replace(/(db)c/, "$1"))

var m = "abcabc".replace(/abc/g, "def").match(/def/g)

print(m)

print( null && "null is not zero!" || "null is zero" )

print( undefined || "ok" || "error" )

function getFunctionName(fun){
  var m = fun.toString().match(/function(\s+)?([a-zA-Z\$_0-9]+)?/)
  //print(fun.toString(), m)
  return m && m[2] || null
}

print(getFunctionName("abc"), getFunctionName("function Test(){}"))

//var o = []
//for( var i in this) 
  //o.push(i+" => "+this[i])
//print(o.join("\n"))

print("someunexpectedvar is", typeof someunexpectedvar)

"complete..."
